package io.github.wppli.domain.authenticate.service.engine.impl;

import cc.jq1024.middleware.redisson.IRedissonService;
import io.github.wppli.domain.authenticate.model.entity.UserEntity;
import io.github.wppli.domain.authenticate.model.entity.SingInEntity;
import io.github.wppli.domain.authenticate.service.engine.IEngine;
import io.github.wppli.types.exception.CacheCodeIllegalException;
import io.github.wppli.types.security.constants.SecurityConstant;
import io.github.wppli.types.security.model.SecurityUser;
import io.github.wppli.types.security.util.CacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

import static io.github.wppli.types.common.Constant.LOGIN_CODE;
import static io.github.wppli.types.enums.ResponseCode.CACHE_CODE_ILLEGAL;

/**
 * 使用验证码方式登录
 * @author li--jiaqiang 2024−12−23
 */
@Slf4j
@Service("codeEngine")
public class CodeEngine implements IEngine {


    private final IRedissonService redissonService;
    private final CacheService cacheService;
    private final UserDetailsService userDetailsService;
    public CodeEngine(IRedissonService redissonService, CacheService cacheService, UserDetailsService userDetailsService) {
        this.redissonService = redissonService;
        this.cacheService = cacheService;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public void loginEngine(SingInEntity singInEntity, UserEntity userEntity) {
        String loginCacheCode = redissonService.getValue(LOGIN_CODE + singInEntity.getContactInformation());
        if (null == loginCacheCode || !loginCacheCode.equals(singInEntity.getPasswordCode())) {
            throw new CacheCodeIllegalException(CACHE_CODE_ILLEGAL.getCode(), CACHE_CODE_ILLEGAL.getInfo(), new Throwable(CACHE_CODE_ILLEGAL.getInfo()));
        }
        // 校验成功，删除验证码
        redissonService.setValue(LOGIN_CODE + singInEntity.getContactInformation(), null, 0, TimeUnit.MICROSECONDS);
        log.info("CodeEngine.loginEngine() 校验通过");

        // 手动调用 userDetailsService() 方法
        SecurityUser securityUser = (SecurityUser) userDetailsService.loadUserByUsername(singInEntity.getContactInformation());
        // 缓存用户信息
        cacheService.setAuthorizationWithUsername(securityUser.getUsername(), securityUser, SecurityConstant.TOKEN_EXPIRE, TimeUnit.SECONDS);
        log.info("用户:{} 验证码登录执行 loadUserByUsername() 方法完成。Cache SecurityUser",securityUser.getUsername());
    }

}